<template>
  <div class="data-table">
    <!-- 工具栏 -->
    <div class="table-toolbar" v-if="showToolbar">
      <div class="toolbar-left">
        <slot name="toolbar-left">
          <!-- 批量操作 -->
          <div
            v-if="showSelection && selectedRowKeys.length > 0"
            class="batch-actions"
          >
            <span class="selected-count"
              >已选择 {{ selectedRowKeys.length }} 项</span
            >
            <el-button size="small" @click="clearSelection">清空选择</el-button>
            <slot name="batch-actions"></slot>
          </div>
        </slot>
      </div>

      <div class="toolbar-right">
        <slot name="toolbar-right">
          <!-- 刷新按钮 -->
          <el-button
            v-if="showRefresh"
            size="small"
            @click="handleRefresh"
            :loading="loading"
          >
            <el-icon><Refresh /></el-icon>
            刷新
          </el-button>

          <!-- 搜索框 -->
          <div v-if="showSearch" class="search-wrapper">
            <el-input
              v-model="searchText"
              placeholder="请输入搜索内容"
              size="small"
              clearable
              @clear="handleSearch"
              @keyup.enter="handleSearch"
            >
              <template #prefix>
                <el-icon><Search /></el-icon>
              </template>
            </el-input>
            <el-button type="primary" size="small" @click="handleSearch">
              搜索
            </el-button>
          </div>
        </slot>
      </div>
    </div>

    <!-- 表格 -->
    <el-table
      ref="tableRef"
      :data="dataSource"
      v-loading="loading"
      :height="height"
      :max-height="maxHeight"
      :stripe="stripe"
      :border="border"
      :row-key="rowKey"
      :default-sort="defaultSort"
      @selection-change="handleSelectionChange"
      @sort-change="handleSortChange"
      @filter-change="handleFilterChange"
    >
      <!-- 选择列 -->
      <el-table-column
        v-if="showSelection"
        type="selection"
        width="55"
        :reserve-selection="reserveSelection"
      />

      <!-- 序号列 -->
      <el-table-column
        v-if="showIndex"
        type="index"
        width="60"
        label="序号"
        :index="indexMethod"
      />

      <!-- 自定义列 -->
      <slot></slot>

      <!-- 操作列 -->
      <el-table-column
        v-if="showActions"
        label="操作"
        :width="actionsWidth"
        :fixed="actionsFixed"
      >
        <template #default="scope">
          <slot name="actions" :row="scope.row" :index="scope.$index">
            <!-- 默认操作按钮 -->
            <el-button
              v-if="showEdit"
              size="small"
              @click="$emit('edit', scope.row)"
            >
              编辑
            </el-button>
            <el-button
              v-if="showDelete"
              size="small"
              type="danger"
              @click="$emit('delete', scope.row)"
            >
              删除
            </el-button>
          </slot>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div class="table-pagination" v-if="showPagination">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="pageSizes"
        :total="total"
        :layout="paginationLayout"
        :background="paginationBackground"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { Refresh, Search } from "@element-plus/icons-vue";

interface Props {
  // 数据源
  dataSource?: any[];
  loading?: boolean;

  // 表格配置
  height?: string | number;
  maxHeight?: string | number;
  stripe?: boolean;
  border?: boolean;
  rowKey?: string | ((row: any) => any);

  // 排序
  defaultSort?: any;

  // 选择
  showSelection?: boolean;
  reserveSelection?: boolean;

  // 序号
  showIndex?: boolean;
  indexMethod?: (index: number) => number;

  // 操作列
  showActions?: boolean;
  actionsWidth?: string | number;
  actionsFixed?: string | boolean;
  showEdit?: boolean;
  showDelete?: boolean;

  // 工具栏
  showToolbar?: boolean;
  showRefresh?: boolean;
  showSearch?: boolean;

  // 分页
  showPagination?: boolean;
  currentPage?: number;
  pageSize?: number;
  total?: number;
  pageSizes?: number[];
  paginationLayout?: string;
  paginationBackground?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  dataSource: () => [],
  loading: false,
  stripe: true,
  border: false,
  showSelection: false,
  reserveSelection: false,
  showIndex: false,
  showActions: true,
  actionsWidth: 150,
  actionsFixed: false,
  showEdit: true,
  showDelete: true,
  showToolbar: true,
  showRefresh: true,
  showSearch: true,
  showPagination: true,
  currentPage: 1,
  pageSize: 20,
  total: 0,
  pageSizes: () => [10, 20, 50, 100],
  paginationLayout: "total, sizes, prev, pager, next, jumper",
  paginationBackground: true,
});

const emit = defineEmits<{
  "update:currentPage": [value: number];
  "update:pageSize": [value: number];
  "selection-change": [selection: any[]];
  "sort-change": [sort: any];
  "filter-change": [filters: any];
  edit: [row: any];
  delete: [row: any];
  refresh: [];
  search: [value: string];
}>();

// 响应式数据
const tableRef = ref();
const selectedRowKeys = ref<any[]>([]);
const selectedRows = ref<any[]>([]);
const searchText = ref("");

// 计算属性
const currentPage = computed({
  get: () => props.currentPage,
  set: (value) => emit("update:currentPage", value),
});

const pageSize = computed({
  get: () => props.pageSize,
  set: (value) => emit("update:pageSize", value),
});

// 方法
const handleSelectionChange = (selection: any[]) => {
  selectedRowKeys.value = selection.map((row) => row.id || row.key);
  selectedRows.value = selection;
  emit("selection-change", selection);
};

const handleSortChange = (sort: any) => {
  emit("sort-change", sort);
};

const handleFilterChange = (filters: any) => {
  emit("filter-change", filters);
};

const handleSizeChange = (size: number) => {
  emit("update:pageSize", size);
};

const handleCurrentChange = (page: number) => {
  emit("update:currentPage", page);
};

const handleRefresh = () => {
  emit("refresh");
};

const handleSearch = () => {
  emit("search", searchText.value);
};

const clearSelection = () => {
  selectedRowKeys.value = [];
  selectedRows.value = [];
  tableRef.value?.clearSelection();
};

// 暴露方法
defineExpose({
  tableRef,
  selectedRowKeys,
  selectedRows,
  clearSelection,
});
</script>

<style scoped>
.data-table {
  .table-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
    padding: 16px;
    background: #fafafa;
    border-radius: 4px;

    .toolbar-left,
    .toolbar-right {
      display: flex;
      align-items: center;
      gap: 12px;
    }

    .batch-actions {
      display: flex;
      align-items: center;
      gap: 8px;

      .selected-count {
        color: #409eff;
        font-weight: 500;
      }
    }

    .search-wrapper {
      display: flex;
      gap: 8px;
    }
  }

  .table-pagination {
    display: flex;
    justify-content: center;
    margin-top: 16px;
    padding: 16px;
  }
}

:deep(.el-table) {
  .el-table__header-wrapper {
    background: #f5f7fa;
  }

  .el-table__row {
    &:hover {
      background: #f5f7fa;
    }
  }
}

:deep(.el-pagination) {
  .el-pager li {
    &:hover {
      color: #409eff;
    }

    &.is-active {
      background: #409eff;
      color: white;
    }
  }
}
</style>
